<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="description" content="PragmaticScala">
<meta name="generator" content="Paradox, paradox-material-theme=0.5.1, mkdocs-material=3.0.3">

<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="">
<meta name="lang:search.pipeline.stopwords" content="true">
<meta name="lang:search.pipeline.trimmer" content="true">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">


<meta name="description" content="PragmaticScala">
<link rel="shortcut icon" href="../assets/images/favicon.png">
<title>第12章——惰性求值和并行集合 · </title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../lib/material__tabs/dist/mdc.tabs.min.css">
<link rel="stylesheet" href="../lib/prettify/prettify.css">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono">
<style>
body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}
code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}
</style>
<link rel="stylesheet" href="../assets/fonts/font-awesome.css">
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../assets/stylesheets/paradox-material-theme.css">
</head>
<body
>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="../index.html" title="" class="md-header-nav__button md-logo">
<i class="md-icon">local_library</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
</span>
<span class="md-header-nav__topic">
第12章——惰性求值和并行集合
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">&#xE5CD;</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>

</div>
</div>
</nav>
</header>

<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0" style="visibility: hidden">
<label class="md-nav__title md-nav__title--site" for="drawer">
<a href="../index.html" title="" class="md-nav__button md-logo">
<span class="md-nav__button md-logo">
<i class="md-icon">local_library</i>
</a>
<a href="../index.html" title="">
</a>
</label>
<ul>
  <li><a href="../contents.html" class="page">目录</a>
  <ul>
    <li><a href="../abstract.html" class="page">内容提要</a></li>
    <li><a href="../part1.html" class="page">第一部分 小试牛刀</a></li>
    <li><a href="../part2.html" class="page">第二部分 深入 Scala</a></li>
    <li><a href="../part3.html" class="page">第三部分 Scala 中的并发编程</a></li>
    <li><a href="../part4.html" class="page">第四部分 Scala 实战</a></li>
    <li><a href="../refs/references.html" class="page">参考书目</a></li>
    <li><a href="../extras.html" class="page">额外指引</a></li>
    <li><a href="../errata.html" class="page">勘误</a></li>
  </ul></li>
</ul>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul>
  <li><a href="../chapter-12/index.html#第12章-惰性求值和并行集合" class="header">第12章——惰性求值和并行集合</a>
  <ul>
    <li><a href="../chapter-12/index.html#12-1-释放惰性" class="header">12.1 释放惰性</a></li>
    <li><a href="../chapter-12/index.html#12-2-释放严格集合的惰性" class="header">12.2 释放严格集合的惰性</a></li>
    <li><a href="../chapter-12/index.html#12-3-终极惰性流" class="header">12.3 终极惰性流</a></li>
    <li><a href="../chapter-12/index.html#12-4-并行集合" class="header">12.4 并行集合</a></li>
  </ul></li>
</ul>
</nav>

</nav>
<ul style="display: none">
<li class="md-nav__item md-version" id="project.version">
<label class="md-nav__link" for="__version">
<i class="md-icon" title="Version">label_outline</i> 1.0.0
</label>
</li>
</ul>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul>
  <li><a href="../chapter-12/index.html#第12章-惰性求值和并行集合" class="header">第12章——惰性求值和并行集合</a>
  <ul>
    <li><a href="../chapter-12/index.html#12-1-释放惰性" class="header">12.1 释放惰性</a></li>
    <li><a href="../chapter-12/index.html#12-2-释放严格集合的惰性" class="header">12.2 释放严格集合的惰性</a></li>
    <li><a href="../chapter-12/index.html#12-3-终极惰性流" class="header">12.3 终极惰性流</a></li>
    <li><a href="../chapter-12/index.html#12-4-并行集合" class="header">12.4 并行集合</a></li>
  </ul></li>
</ul>
</nav>

</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<div class="md-content__searchable">
<h1><a href="#第12章-惰性求值和并行集合" name="第12章-惰性求值和并行集合" class="anchor"><span class="anchor-link"></span></a>第12章——惰性求值和并行集合</h1>
<p>即时响应性是一项决定任何应用程序成败的关键因素。其他因素，如商业价值、易用性、 可用性、成本以及回弹性，也很重要，但是即时响应性是最重要的—我们人类大约需要 250 ms 来感知任何的移动，超过 5 s 的延迟就变得不可接受了。任何可以降低响应时间的努力都会 产生巨大的影响，能够使客户更加满意，进而赢得他们的信任。</p>
<h2><a href="#12-1-释放惰性" name="12-1-释放惰性" class="anchor"><span class="anchor-link"></span></a>12.1 释放惰性</h2>
<blockquote>
  <p>Parallel/ShortCircuit.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">def expensiveComputation() = {
  println(&quot;...assume slow operation...&quot;)
  false
}

def evaluate(input: Int): Unit = {
  println(s&quot;evaluate called with $input&quot;)
  if (input &gt;= 10 &amp;&amp; expensiveComputation())
    println(&quot;doing work...&quot;)
  else
    println(&quot;skipping&quot;)
}

evaluate(0)
evaluate(100)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/ShortCircuit.scala#L21-L35">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">evaluate called with 0
skipping
evaluate called with 100
...assume slow operation...
skipping</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/shortCircuit.output#L2-L6">Full source at GitHub</a>
<blockquote>
  <p>Parallel/Eager.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">val perform = expensiveComputation()
if (input &gt;= 10 &amp;&amp; perform)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/Eager.scala#L28-L29">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">evaluate called with 0
...assume slow operation...
skipping
evaluate called with 100
...assume slow operation...
skipping</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/eager.output#L2-L7">Full source at GitHub</a>
<blockquote>
  <p>Parallel/Eager.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">@volatile lazy val perform = expensiveComputation()
if (input &gt;= 10 &amp;&amp; perform)
  println(&quot;doing work...&quot;)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/Lazy.scala#L28-L30">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">evaluate called with 0
skipping
evaluate called with 100
...assume slow operation...
skipping</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/lazy.output#L2-L6">Full source at GitHub</a>
<blockquote>
  <p>Parallel/LazyOrder.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">import scala.io._

def read = StdIn.readInt()

@volatile lazy val first = read
@volatile lazy val second = read

if (Math.random() &lt; 0.5)
  second

println(first - second)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/LazyOrder.scala#L21-L31">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">&gt; scala LazyOrder.scala
1
2
1
&gt; scala LazyOrder.scala
1
2
-1
&gt;</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/lazyOrder.output#L2-L10">Full source at GitHub</a>
<h2><a href="#12-2-释放严格集合的惰性" name="12-2-释放严格集合的惰性" class="anchor"><span class="anchor-link"></span></a>12.2 释放严格集合的惰性</h2>
<blockquote>
  <p>Parallel/StrictCollection.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">val people = List((&quot;Mark&quot;, 32), (&quot;Bob&quot;, 22), (&quot;Jane&quot;, 8), (&quot;Jill&quot;, 21),
  (&quot;Nick&quot;, 50), (&quot;Nancy&quot;, 42), (&quot;Mike&quot;, 19), (&quot;Sara&quot;, 12), (&quot;Paula&quot;, 42),
  (&quot;John&quot;, 21))

def isOlderThan17(person: (String, Int)) = {
  println(s&quot;isOlderThan17 called for $person&quot;)
  val (_, age) = person
  age &gt; 17
}

def isNameStartsWithJ(person: (String, Int)) = {
  println(s&quot;isNameStartsWithJ called for $person&quot;)
  val (name, _) = person
  name.startsWith(&quot;J&quot;)
}

println(people.filter { isOlderThan17 }.filter { isNameStartsWithJ }.head)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/StrictCollection.scala#L21-L37">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">isOlderThan17 called for (Mark,32)
isOlderThan17 called for (Bob,22)
isOlderThan17 called for (Jane,8)
isOlderThan17 called for (Jill,21)
isOlderThan17 called for (Nick,50)
isOlderThan17 called for (Nancy,42)
isOlderThan17 called for (Mike,19)
isOlderThan17 called for (Sara,12)
isOlderThan17 called for (Paula,42)
isOlderThan17 called for (John,21)
isNameStartsWithJ called for (Mark,32)
isNameStartsWithJ called for (Bob,22)
isNameStartsWithJ called for (Jill,21)
isNameStartsWithJ called for (Nick,50)
isNameStartsWithJ called for (Nancy,42)
isNameStartsWithJ called for (Mike,19)
isNameStartsWithJ called for (Paula,42)
isNameStartsWithJ called for (John,21)
(Jill,21)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/strictCollection.output#L2-L20">Full source at GitHub</a>
<blockquote>
  <p>Parallel/LazyCollection.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">println(people.view.filter { isOlderThan17 }.filter { isNameStartsWithJ }.head)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/LazyCollection.scala#L37">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">isOlderThan17 called for (Mark,32)
isNameStartsWithJ called for (Mark,32)
isOlderThan17 called for (Bob,22)
isNameStartsWithJ called for (Bob,22)
isOlderThan17 called for (Jane,8)
isOlderThan17 called for (Jill,21)
isNameStartsWithJ called for (Jill,21)
(Jill,21)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/lazyCollection.output#L2-L9">Full source at GitHub</a>
<h2><a href="#12-3-终极惰性流" name="12-3-终极惰性流" class="anchor"><span class="anchor-link"></span></a>12.3 终极惰性流</h2>
<blockquote>
  <p>Parallel/NumberGenerator.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">def generate(starting: Int): Stream[Int] = {
  starting #:: generate(starting + 1)
}

println(generate(25))</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/NumberGenerator.scala#L21-L25">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">Stream(25, ?)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/numberGenerator.output#L2">Full source at GitHub</a>
<blockquote>
  <p>Parallel/NumberGenerator.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">println(generate(25).take(10).force)
println(generate(25).take(10).toList)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/NumberGenerator.scala#L29-L30">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">Stream(25, 26, 27, 28, 29, 30, 31, 32, 33, 34)
List(25, 26, 27, 28, 29, 30, 31, 32, 33, 34)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/numberGenerator.output#L6-L7">Full source at GitHub</a>
<blockquote>
  <p>Parallel/NumberGenerator.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">println(generate(25).takeWhile { _ &lt; 40 }.force)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/NumberGenerator.scala#L34">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">Stream(25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/numberGenerator.output#L11">Full source at GitHub</a>
<blockquote>
  <p>Parallel/Primes.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">def isDivisibleBy(number: Int, divisor: Int) = number % divisor == 0

def isPrime(number: Int) =
  number &gt; 1 &amp;&amp; !(2 until number).exists { isDivisibleBy(number, _) }

def primes(starting: Int): Stream[Int] = {
  println(s&quot;computing for $starting&quot;)
  if (isPrime(starting))
    starting #:: primes(starting + 1)
  else
    primes(starting + 1)
}</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/Primes.scala#L21-L32">Full source at GitHub</a>
<blockquote>
  <p>Parallel/Primes.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">val primesFrom100 = primes(100)

println(primesFrom100.take(3).toList)
println(&quot;Let&#39;s ask for more...&quot;)
println(primesFrom100.take(4).toList)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/Primes.scala#L36-L40">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">computing for 100
computing for 101
computing for 102
computing for 103
computing for 104
computing for 105
computing for 106
computing for 107
List(101, 103, 107)
Let&#39;s ask for more...
computing for 108
computing for 109
List(101, 103, 107, 109)</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/primes.output#L2-L14">Full source at GitHub</a>
<h2><a href="#12-4-并行集合" name="12-4-并行集合" class="anchor"><span class="anchor-link"></span></a>12.4 并行集合</h2>
<blockquote>
  <p>Parallel/Weather.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">import scala.io.Source
import scala.xml._

def getWeatherData(city: String) = {
  val response = Source.fromURL(
    s&quot;https://raw.githubusercontent.com/ReactivePlatform/&quot; +
      s&quot;Pragmatic-Scala-StaticResources/master/src/main/resources/&quot; +
      s&quot;weathers/$city.xml&quot;)
  val xmlResponse = XML.loadString(response.mkString)
  val cityName = (xmlResponse \\ &quot;city&quot; \ &quot;@name&quot;).text
  val temperature = (xmlResponse \\ &quot;temperature&quot; \ &quot;@value&quot;).text
  val condition = (xmlResponse \\ &quot;weather&quot; \ &quot;@value&quot;).text
  (cityName, temperature, condition)
}</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/Weather.scala#L21-L34">Full source at GitHub</a>
<blockquote>
  <p>Parallel/Weather.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">def printWeatherData(weatherData: (String, String, String)): Unit = {
  val (cityName, temperature, condition) = weatherData

  println(f&quot;$cityName%-15s $temperature%-6s $condition&quot;)
}</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/Weather.scala#L38-L42">Full source at GitHub</a>
<blockquote>
  <p>Parallel/Weather.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">def timeSample(getData: List[String] ⇒ List[(String, String, String)]): Unit = {
  val cities = List(&quot;Houston,us&quot;, &quot;Chicago,us&quot;, &quot;Boston,us&quot;, &quot;Minneapolis,us&quot;,
    &quot;Oslo,norway&quot;, &quot;Tromso,norway&quot;, &quot;Sydney,australia&quot;, &quot;Berlin,germany&quot;,
    &quot;London,uk&quot;, &quot;Krakow,poland&quot;, &quot;Rome,italy&quot;, &quot;Stockholm,sweden&quot;,
    &quot;Bangalore,india&quot;, &quot;Brussels,belgium&quot;, &quot;Reykjavik,iceland&quot;)

  val start = System.nanoTime
  getData(cities).sortBy(_._1).foreach(printWeatherData)
  val end = System.nanoTime
  println(s&quot;Time taken: ${(end - start) / 1.0e9} sec&quot;)
}
</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/Weather.scala#L46-L57">Full source at GitHub</a>
<blockquote>
  <p>Parallel/Weather.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">timeSample { cities ⇒ cities map getWeatherData }</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/Weather.scala#L61">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">Bengaluru       84.2   few clouds
Berlin          45.63  broken clouds
Boston          52.23  scattered clouds
Brussels        50.83  Sky is Clear
Chicago         46.13  sky is clear
Cracow          40.39  moderate rain
Houston         54.01  light intensity drizzle
London          55.33  Sky is Clear
Minneapolis     42.82  sky is clear
Oslo            47.3   Sky is Clear
Reykjavik       31.17  proximity shower rain
Rome            58.42  few clouds
Stockholm       47.28  Sky is Clear
Sydney          68.9   Sky is Clear
Tromso          35.6   proximity shower rain
Time taken: 67.208944087 sec</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/weather.output#L2-L17">Full source at GitHub</a>
<blockquote>
  <p>Parallel/Weather.scala</p>
</blockquote>
<pre class="prettyprint"><code class="language-scala">timeSample { cities ⇒ (cities.par map getWeatherData).toList }</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/Weather.scala#L65">Full source at GitHub</a>
<p><em>运行结果</em></p>
<pre class="prettyprint"><code class="language-output">Bengaluru       84.2   few clouds
Berlin          45.63  broken clouds
Boston          52.23  scattered clouds
Brussels        50.83  Sky is Clear
Chicago         46.13  sky is clear
Cracow          40.39  moderate rain
Houston         54.01  light intensity drizzle
London          55.33  Sky is Clear
Minneapolis     42.82  sky is clear
Oslo            47.3   Sky is Clear
Reykjavik       31.17  proximity shower rain
Rome            58.42  few clouds
Stockholm       47.28  Sky is Clear
Sydney          68.9   Sky is Clear
Tromso          35.6   proximity shower rain
Time taken: 0.171599394 sec</code></pre><a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/v1.0.0/src/main/scala/chapter12/output/weather.output#L21-L36">Full source at GitHub</a>
</div>
<div>
<a href="https://github.com/ReactivePlatform/Pragmatic-Scala.git/tree/master/src/paradox/chapter-12/index.md" title="Edit this page" class="md-source-file md-edit">
Edit this page
</a>
</div>
<div class="print-only">
<span class="md-source-file md-version">
1.0.0
</span>
</div>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../part3.html" title="第三部分 Scala 中的并发编程" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
第三部分 Scala 中的并发编程
</span>
</div>
</a>
<a href="../chapter-13/index.html" title="第13章——使用Actor编程" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
第13章——使用Actor编程
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
Powered by
<a href="https://github.com/lightbend/paradox">Paradox</a>
and
<a href="https://jonas.github.io/paradox-material-theme/">Paradox Material Theme</a>

</div>
</div>
</div>
</footer>

</div>
<script src="../assets/javascripts/application.583bbe55.js"></script>
<script src="../assets/javascripts/paradox-material-theme.js"></script>
<script>app.initialize({version:"0.17",url:{base:"../."}})</script>
<script type="text/javascript" src="../lib/prettify/prettify.js"></script>
<script type="text/javascript" src="../lib/prettify/lang-scala.js"></script>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(event) {
window.prettyPrint && prettyPrint();
});
</script>
</body>
</html>
